package com.lebang.service.buss;

import com.alibaba.fastjson.JSONObject;
import com.lebang.common.util.ShowDateUtil;
import com.lebang.entity.RequestHeaders;
import com.lebang.entity.member.LbbMemberRecord;
import com.lebang.entity.task.LbbCommon;
import com.lebang.entity.task.LbbSosoWithBLOBs;
import com.lebang.entity.task.TaskComments;
import com.lebang.entity.task.TaskScreenshot;
import com.lebang.example.LbbMemberRecordExample;
import com.lebang.mapper.LbbCommonMapper;
import com.lebang.mapper.LbbMemberMapper;
import com.lebang.mapper.LbbMemberRecordMapper;
import com.lebang.mapper.TaskScreenshotMapper;
import com.lebang.model.MyConfig;
import com.lebang.model.back.Result;
import com.lebang.model.enums.Booleans;
import com.lebang.model.enums.buss.RewardType;
import com.lebang.model.enums.buss.TaskCategory;
import com.lebang.model.enums.buss.TaskStatus;
import com.lebang.model.excel.CommonExcel;
import com.lebang.model.recordback.MemberRecordLog;
import com.lebang.model.recordback.RecordPage;
import com.lebang.model.statistics.RecordModel;
import com.lebang.model.statistics.StatisticsRecord;
import com.lebang.service.task.TaskService;
import com.lebangweb.common.DateUtil;
import com.lebangweb.common.TextUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * 用户任务完成记录
 *
 * @author weizx
 * @className MemberRecordService
 * @date 2018年7月20日 下午4:35:02
 */
@Service
public class MemberRecordService {

    @Autowired
    private LbbMemberRecordMapper lbbMemberRecordMapper;
    @Autowired
    private LbbCommonMapper commonMapper;
    @Autowired
    private LbbMemberMapper lbbMemberMapper;
    @Autowired
    private TaskScreenshotMapper taskScreenshotMapper;
    @Resource(name = "sosoTaskService")
    private TaskService<LbbSosoWithBLOBs> sosoTaskService;
    @Resource(name = "commonTaskService")
    private TaskService<LbbCommon> commonTaskService;
    @Resource(name = "commentsTaskService")
    private TaskService<TaskComments> commentsTaskService;
    @Resource(name = "multiwordservice")
    private TaskService<LbbCommon> multiwordTaskService;
    @Value("${spring.application.name}")
    private String serverName;


    /**
     * 任务已完成数
     *
     * @param category
     * @param taskid
     * @param stime
     * @param etime
     * @return
     * @author weizx
     * @date 2018年7月20日 下午4:35:12
     */
    public int total(String category, String taskid, String stime, String etime) {
        return lbbMemberRecordMapper.searchTotal(category, taskid, stime, etime);
    }

    /**
     * 任务执行列表
     *
     * @param category
     * @param status
     * @param stime
     * @param etime
     * @return
     * @author weizx
     * @date 2018年8月1日 下午3:30:22
     */
    public Map<String, Object> pagging(String category, String status, String stime, String etime, Integer offset, Integer limit, String title, String customer, String phone, Integer statust) {
        title = title == null ? "" : title;
        customer = customer == null ? "" : customer;
        int total = lbbMemberRecordMapper.total(category, status, stime, etime, title, customer, phone, statust);
        List<Map<String, Object>> rows = lbbMemberRecordMapper.pagging(category, status, stime, etime, offset, limit, title, customer, phone, statust);
        Map<String, Object> data = new LinkedHashMap<String, Object>();
        data.put("total", total);
        data.put("rows", rows);
        return data;
    }

    public Map<String, Object> getPhone(String taskId, String stime, String etime) {
        int total = lbbMemberRecordMapper.totals(taskId, stime, etime);
        List<Map<String, Object>> rows = lbbMemberRecordMapper.getPhone(taskId, stime, etime);
        Map<String, Object> data = new LinkedHashMap<String, Object>();
        data.put("total", total);
        data.put("rows", rows);
        return data;
    }

    public Map<String, Object> none(String taskId, String stime, String etime) {
        int total = lbbMemberRecordMapper.nones(taskId, stime, etime);
        List<Map<String, Object>> rows = lbbMemberRecordMapper.none(taskId, stime, etime);
        Map<String, Object> data = new LinkedHashMap<String, Object>();
        data.put("total", total);
        data.put("rows", rows);
        return data;
    }

    public Map<String, Object> checkFailure(String taskId, String stime, String etime) {
        int total = lbbMemberRecordMapper.checkFailures(taskId, stime, etime);
        List<Map<String, Object>> rows = lbbMemberRecordMapper.checkFailure(taskId, stime, etime);
        Map<String, Object> data = new LinkedHashMap<String, Object>();
        data.put("total", total);
        data.put("rows", rows);
        return data;
    }

    public Map<String, Object> checkSuccess(String taskId, String stime, String etime) {
        int total = lbbMemberRecordMapper.checkSuccesss(taskId, stime, etime);
        List<Map<String, Object>> rows = lbbMemberRecordMapper.checkSuccess(taskId, stime, etime);
        Map<String, Object> data = new LinkedHashMap<String, Object>();
        data.put("total", total);
        data.put("rows", rows);
        return data;
    }


    public Integer insertSelective(LbbMemberRecord memberRecord) {
        return lbbMemberRecordMapper.insertSelective(memberRecord);
    }


    public long findCount(String star, String end, String title, String tableName, String userid, String customerid) {
        return lbbMemberRecordMapper.findCount(star, end, title, tableName, userid, customerid);
    }

    public List<Map<String, Object>> findList(Integer startNum, Integer limit, String star, String end, String title, String tableName, String userid, String customerid) {
        return lbbMemberRecordMapper.findList(startNum, limit, star, end, title, tableName, userid, customerid);
    }

    public long finddetailCount(String taskId, String star, String end) {
        return lbbMemberRecordMapper.finddetailCount(taskId, star, end);
    }

    public List<Map<String, Object>> finddetailList(Integer startNum, Integer limit, String tableName, String taskId, String star, String end) {
        return lbbMemberRecordMapper.finddetailList(startNum, limit, tableName, taskId, star, end);
    }

    public List<Long> getSuccess(String star, String end) {
        return lbbMemberRecordMapper.getSuccess(star, end);
    }

    public Long getTrade(String star, String end) {
        return lbbMemberRecordMapper.getTrade(star, end);
    }


    public LbbMemberRecord selectByid(Integer id, String userid) {
        return lbbMemberRecordMapper.selectByid(id, null, userid);
    }

    /**
     * 查询任务是否做过
     *
     * @param memberId 会员id
     * @param taskId   任务id
     * @param category 任务类型
     * @return 任务
     */
    public LbbMemberRecord checkRecord(String memberId, String taskId, String category) {
        return lbbMemberRecordMapper.checkRecord(memberId, taskId, category, null, null);
    }

    public LbbMemberRecord checkRecord(String memberId, String taskId, String category, String imei) {
        return lbbMemberRecordMapper.checkRecord(memberId, taskId, category, imei, null);
    }

    public LbbMemberRecord checkRecord(String memberId, String taskId, String category, TaskStatus status) {
        return lbbMemberRecordMapper.checkRecord(memberId, taskId, category, null, status);
    }

    /**
     * 添加任务
     */
    public int insertRecord(LbbMemberRecord lbbMemberRecord) {
        lbbMemberRecord.setHasDeleted(Booleans.False.name());
        return lbbMemberRecordMapper.insertSelective(lbbMemberRecord);
    }

    /**
     * 添加任务
     */
    public int insertRecord(TaskCategory category, String taskId,
                            String memberId, RequestHeaders requsetHeader,
                            TaskStatus status, String result, String orderId,
                            Booleans booleans, Integer userMoney, Integer increase, String title) {
        LbbMemberRecord record = new LbbMemberRecord();
        record.setCreateTime(new Date());
        record.setHasDeleted(Booleans.False.name());
        record.setAppId(requsetHeader.getAppid());
        record.setAppStore(requsetHeader.getAppStore());
        record.setCategory(category);
        record.setImei(requsetHeader.getImei());
        record.setIpAddr(requsetHeader.getIpAddr());
        record.setMacAddr(requsetHeader.getMacAddr());
        record.setMemberId(memberId);
        record.setNeedChecked(booleans);
        record.setOrderId(orderId);
        record.setOs(requsetHeader.getOs());
        record.setOsv(requsetHeader.getOsv());
        record.setResult(result);
        record.setStatus(status);
        record.setTaskId(taskId);
        record.setUserId("");
        record.setVersion(requsetHeader.getVersion());
        record.setUserMoney(userMoney);
        record.setIncrease(increase);
        record.setUa(requsetHeader.getUa());
        record.setTaskTitle(title);
        lbbMemberRecordMapper.insertSelective(record);
        return record.getId().intValue();
    }

    /**
     * 添加任务
     */
    public int insertRecord(TaskCategory category, String taskId, String memberId,
                            RequestHeaders requsetHeader, TaskStatus status, String result,
                            String orderId, Booleans booleans, Integer redo, Integer userMoney,
                            Integer increase, RewardType type, String title) {
        LbbMemberRecord record = new LbbMemberRecord();
        record.setCreateTime(new Date());
        record.setHasDeleted(Booleans.False.name());
        record.setAppId(MyConfig.getEnv().toString());
        record.setAppStore(requsetHeader.getAppStore());
        record.setCategory(category);
        record.setImei(requsetHeader.getImei());
        record.setIpAddr(requsetHeader.getIpAddr());
        record.setMacAddr(requsetHeader.getMacAddr());
        record.setMemberId(memberId);
        record.setNeedChecked(booleans);
        record.setOrderId(orderId);
        record.setOs(requsetHeader.getOs());
        record.setOsv(requsetHeader.getOsv());
        record.setResult(result);
        record.setStatus(status);
        record.setTaskId(taskId);
        record.setUserId("");
        record.setVersion(requsetHeader.getVersion());
        record.setRedo(redo);
        record.setUserMoney(userMoney);
        record.setIncrease(increase);
        record.setRewordType(type.getIndex());
        record.setTaskTitle(title);
        record.setPhone(lbbMemberMapper.selectPhoneByMemberId(memberId));
        record.setServerName(serverName);
        lbbMemberRecordMapper.insertSelective(record);
        return record.getId().intValue();
    }

    /**
     * 修改任务
     **/
    public int updateRecord(LbbMemberRecord record) {
        return lbbMemberRecordMapper.updateByPrimaryKeySelective(record);
    }

    /**
     * 修改任务
     **/
    public int updateByPrimaryKeySelective(LbbMemberRecord record) {
        return lbbMemberRecordMapper.updateByPrimaryKeySelective(record);
    }

    public List<LbbMemberRecord> getListByExample(LbbMemberRecordExample lbbMemberRecordExample) {
        return lbbMemberRecordMapper.selectbyexamplewithblobs(lbbMemberRecordExample);
    }

    public LbbMemberRecord getByMemberIdandTaskid(String taskId, String memeberId, String remark) {
        return lbbMemberRecordMapper.getByMemberIdandTaskid(taskId, memeberId, remark);
    }

    public Long countByExample(LbbMemberRecordExample example) {
        return lbbMemberRecordMapper.countByExample(example);
    }

    /***搜搜任务完成列表*/
    public RecordPage sosoHasCompleted(String userid, Integer page, Integer size) {
        RecordPage recordPage = new RecordPage();
        List<MemberRecordLog> recordCallBacks = lbbMemberRecordMapper.sosoHasCompleted(userid, page, size);
        recordPage.setRows(recordCallBacks);
        recordPage.setPage(page);
        recordPage.setSize(size);
        return recordPage;
    }

    /**
     * 唤醒任务记录
     */
    public LbbMemberRecord get(String userid, String taskid) {
        String tb = "";
        Date today1 = new Date();
        Date tomr = DateUtil.getAfterDate(today1, 1);
        String edate = DateUtil.dateToString(tomr, "yyyy-MM-dd");
        String sdate = DateUtil.dateToString(today1, "yyyy-MM-dd");
        return lbbMemberRecordMapper.queryrouse(tb, userid, taskid, sdate, edate);
    }



    public List<LbbMemberRecord> getList(String taskId, String stime, String etime) {
        String tb = "";
        return lbbMemberRecordMapper.getList(tb, taskId, stime, etime);
    }

    public void cleanByMemberId(String memberId, List<LbbMemberRecord> records) {
        for (Iterator<LbbMemberRecord> iterator = records.iterator(); iterator.hasNext(); ) {
            LbbMemberRecord vo = iterator.next();
            if (vo.getRedo() > 0) {
                vo.setStatus(TaskStatus.CheckFailure);
                vo.setRemark("重做任务放弃后不可再领取!");

                //审核失败,重新提交后放弃任务,redo为最大可重做次数
                TaskScreenshot taskScreenshot = taskScreenshotMapper.selectByTaskId(vo.getTaskId());
                vo.setRedo(taskScreenshot.getFailTimes());

                lbbMemberRecordMapper.updateByPrimaryKeySelective(vo);
                iterator.remove();
            }
        }
        lbbMemberRecordMapper.cleanByMemberId(memberId, TaskStatus.WaitSumbit.name());
        records.forEach(vo -> {

            switch (vo.getCategory()) {
                case Comments:
                    commentsTaskService.releaseTask(vo);
                    break;
                case Soso:
                    sosoTaskService.releaseTask(vo);
                    break;
                case Common:
                    LbbCommon common = commonMapper.getByTaskId(vo.getTaskId());
                    if (common.getIsMultiword() == 0) {
                        commonTaskService.releaseTask(vo);
                    } else {
                        multiwordTaskService.releaseTask(vo);
                    }
                    break;
                default:
                    break;
            }
        });
    }

    public List<LbbMemberRecord> selectMemberRecordStatus(String memberId, String name) {
        return lbbMemberRecordMapper.selectMemberRecordStatus(memberId, name);
    }

    public void updateCash(String phone) {
        lbbMemberMapper.updateByPhone(phone);
    }

    public List<LbbMemberRecord> getRecord(String taskid, TaskStatus status, TaskCategory taskCategory) {
        LbbMemberRecordExample lbbMemberRecordExample = new LbbMemberRecordExample();
        LbbMemberRecordExample.Criteria criteria = lbbMemberRecordExample.createCriteria();
        criteria.andTaskIdEqualTo(taskid);
        criteria.andCategoryEqualTo(taskCategory.name());
        criteria.andNeedCheckedEqualTo("True");
        criteria.andStatusEqualTo(status.name());
        return lbbMemberRecordMapper.selectbyexamplewithblobs(lbbMemberRecordExample);

    }

    public int sumMemberTradeByTime(String appStore, LocalDateTime star, LocalDateTime end, int type) {
        return lbbMemberRecordMapper.sumMemberTradeByTime(appStore, star, end, type);
    }

    public List<StatisticsRecord> sumRecordByTime(LocalDateTime star, LocalDateTime end) {
        return lbbMemberRecordMapper.sumRecordByTime(star, end);
    }

    public List<RecordModel> getAllTitleList() {
        return lbbMemberRecordMapper.getAllTitleList();
    }


    public List<CommonExcel> selectByTaskIdAndCategory(String taskId, String category, List<String> status, Date star, Date end) {

        if (TextUtil.isEmpty(star, end)) {
            star = null;
            end = null;
        }

        return lbbMemberRecordMapper.selectByTaskIdAndCategory(taskId, category, status, star, end);
    }

    /**
     * 是否显示任务提示
     * 1.提示待提交的任务
     * 2.提示有待重做的任务，且该任务没有超时
     *
     * @param memberId
     * @return
     */
    public Result<JSONObject> getByMemberId(String memberId) {
        Result<JSONObject> result=new Result();
        JSONObject jsonObject=new JSONObject();
        LbbMemberRecord memberRecord = lbbMemberRecordMapper.getByMemberId(memberId);

        if (memberRecord != null) {
            LocalDateTime ldt = memberRecord.getCreateTime().toInstant()
                    .atZone(ZoneId.systemDefault())
                    .toLocalDateTime();
            long l = Duration.between(ldt, LocalDateTime.now()).toHours();
            //超过24不提示
            if (l>24){
                jsonObject.put("isTrue",false);
                result.setData(jsonObject);
                return result;
            }
            jsonObject.put("taskId",memberRecord.getTaskId());
            jsonObject.put("status",memberRecord.getStatus().name());
            TaskScreenshot taskScreenshot = taskScreenshotMapper.selectByTaskId(memberRecord.getTaskId());
            jsonObject.put("category",taskScreenshot.getCategory());
            //审核失败
            if (memberRecord.getStatus().name().equals(TaskStatus.CheckFailure.name())) {
                //审核失败且重做次数不大1,可重做次数不为零
                if (memberRecord.getRedo() <= 1 && taskScreenshot.getFailTimes()!=0 && !memberRecord.getRedo().equals(taskScreenshot.getFailTimes())) {
                    jsonObject.put("isTrue",true);
                }else {
                    jsonObject.put("isTrue",false);
                }
            }else{
                //待提交状态且超时
                if (isOverTime(memberRecord.getCreateTime(),taskScreenshot.getReleaseTime())){
                    jsonObject.put("isTrue",true);
                }else {
                    jsonObject.put("isTrue",false);
                }
            }
        }
        result.setData(jsonObject);
        return result;
    }

    //是否超时
    public Boolean isOverTime(Date time, Integer releaseTime) {
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        if (releaseTime == null) {
            releaseTime = 30;
        }
        LocalDateTime overtime = LocalDateTime.parse(ShowDateUtil.afterMinute(time, releaseTime), df);
                if (LocalDateTime.now().isAfter(overtime)) {
            return false;
        }
        return true;
    }

    public void updateMultipleById(Integer multiple, Long id) {
        lbbMemberRecordMapper.updateMultipleById(multiple,id);
    }
}
